Record C#

Record C#

👹

重载运算符

  • 格式
    • 访问修饰符 static 返回类型 operator+ (参数列表)

里氏替换原则

  • 尽量不要重写父类方法,而是尽量去扩展父类方法
  • 重写父类方法时,输入参数可以放大,输出结果可以缩小
  • 不要抛出新的异常
  • 如果子类不能完整地实现父类的方法,可以抛出异常或者使用assert等方式提示

拆箱装修

  • 避免装箱和拆箱,可以使用重载方法,泛型容器,接口
    1
    2
    3
    4
    5
    6
    7
    8
    // 强制类型转换
    int i = 10;
    double d = (double)i; // 将整数转换为浮点数
    //------------------
    // 装箱和拆箱
    int j = 20;
    object obj = j; // 装箱:将整数转换为对象
    int k = (int)obj; // 拆箱:将对象转换为整数

封装 与 密封类

  • 封装
    • 封装:指的是将类的实现细节隐藏起来,只对外部提供必要的接口和属性,从而保证类的安全性和稳定性。封装可以通过访问修饰符(public、private、protected等)来实现。
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      public class MyClass
      {
      private int myPrivateField; // 只能在类的内部访问

      public int MyPublicProperty // 可以在类的外部访问
      {
      get { return myPrivateField; }
      set { myPrivateField = value; }
      }
      }

  • 密封类
    • 使用sealed关键字修饰的类,该类不能被其他程序集继承。可以继承其他类,但只能在同一个程序集,保证类的稳定性和安全性。
      1
      2
      3
      4
      5
      sealed class MyClass
      {
      // class definition
      }

多态

  • virtual 关键字用于定义可以被重写但不是必须被重写的方法,而 abstract 关键字用于定义必须在子类中被重写的方法都 搭配 override 关键字
  • 抽象类是不能被实例化的类,只能被继承。
  • 抽象函数是指没有实现的函数,只包含函数的声明。
  • 抽象函数必须在抽象类中定义,不能在普通类中定义。
  • 子类必须实现抽象函数才能被实例化。
  • 子类必须实现所有的抽象方法,否则子类也必须是抽象类。

结构体和类的区别

  • 内存分配:结构体是值类型,它们在栈上分配内存,而类是引用类型,它们在堆上分配内存。
  • 继承:结构体不支持继承,而类支持继承。
  • 默认构造函数:结构体有一个默认构造函数,它会将所有成员变量初始化为默认值,而类必须显式定义构造函数。
  • 性能:由于结构体是值类型,它们在传递和赋值时会进行复制,这可能会影响性能。 而类是引用类型,它们在传递和赋值时只是传递引用,因此性能更高。
  • 当需要封装少量数据时,结构体更为适合,而当需要封装复杂的数据和行为时,类更为适合。

访问其他脚本数据

  • ⭐ static 、 GetComponent
  • GetComponentInChildren:在子物体中查找脚本组件。
    • MyScript myScript = GetComponentInChildren();
  • FindObjectOfType:在场景中查找指定类型的第一个对象。
    • // 在场景中查找指定类型的第一个对象
    • MyScript myScript = FindObjectOfType();
  • FindObjectsOfType:在场景中查找指定类型的所有对象。
    • // 在场景中查找指定类型的所有对象
    • MyScript[] myScripts = FindObjectsOfType();
  • SendMessage:向具有指定名称的所有脚本发送消息。
    • // 向所有脚本发送消息
    • SendMessage(“MyFunction”);
  • 补充(LINQ)
    msedge_33ld0ib96X.png

泛型约束

  • 值类型
    • where 泛型字母:struct
  • 引用类型
    • where 泛型字母:class
  • 存在无参公共构造函数
    • where 泛型字母:new()
  • 某个类本身或者其派生类
    • where 泛型字母:类名
  • 某个接口的派生类型
    • where 泛型字母:接口名
  • 另一个泛型本身或派生类型
    • where 泛型字母:另一个泛型字母

数据集合

  • 需要频繁修改数据时,请使用链表,因为它允许快速插入和删除元素。
  • 需要按位置访问元素时,请使用List,因为它提供了对元素的快速随机访问。
  • 有一个小型数据集并且需要按索引访问元素时,请使用数组,因为它是此用例中内存效率最高的数据结构。
  • 需要实现先进先出 (FIFO) 数据结构时,请使用Queue,因为它可以有效地从队列开头插入和删除元素。
  • 需要实现后进先出 (LIFO) 数据结构时,请使用Stack,因为它可以有效地从堆栈顶部插入和删除元素。

Lambda常用方法

  • Where
  • Select
  • OrderBy
  • ThenBy
  • GroupBy
  • Join
  • GroupJoin

协变逆变

  • 通常与委托和接口有关
    • in、out用于修饰泛型的占位符
      • in代表只能出现在参数
      • out代表只能出现在返回值

多线程

  • 首先要被调用的函数应该先存在于内存中然后再用Thread方法开启
  • 后台线程
    • 后台线程相当于主线程的寄生虫,当主线程死亡,后台线程也死亡
  • 休眠
    • 在哪个线程里执行就休眠哪个
  • 注意事项
    • 如果不是死循环,不必刻意关闭
    • 如果是有两种方案
      • bool开关
      • 线程提供的方法(不建议)
    • ⭐加锁
      • 由于多线程数据会共享 会出现许多未知错误
      • 使用方法
        • 先定义一个引用类型obj
        • 在线程执行语句块外面加lock(obj)
        • 缺点:效率影响
          1
          2
          3
          lock(obj){
          //code block
          }

预处理器

  • #if 可以判断数值

反射

msedge_6jAAAEf3GO.png

  • 三种获取Type的方法
    • 变量.GetType(“要加命名空间.具体的类”);
    • typeof(“要加命名空间.具体的类”)
    • Type.GetType(“要加命名空间.具体的类”)
  • 可以调用别人的代码集
    • Activator快速实例化
    • Assembly程序集类

特性

继承于Attribute基类,用于给类、方法加特性

  • [MyCustom[Attribute](“this is a class for calculate”)]

反射

  • 可以理解为在运行时读懂当前项目中定义的类型(类、结构体等)和成员(方法、变量等)信息,然后进行动态使用。
作者

发布于

2023-05-20

更新于

2023-06-13

许可协议